﻿//-----------------------------------------------------------------------------
// 文件：CBOARD.Cpp
// 功能：Board 的类实现
//-----------------------------------------------------------------------------
#include "dxstdafx.h"
#include "GuiBorder.h"

CGuiBorder::CGuiBorder()
{
	m_pVB = NULL;
	m_pIB = NULL;
	m_pDecl = NULL;
	m_pEffect = NULL;
	m_dwNumVertices = 0;
	m_nOffsetX = 0;
	m_nOffsetY = 0;
	m_nWidth = 0;
	m_nHeight = 0;
}

CGuiBorder::~CGuiBorder()
{
	SAFE_RELEASE(m_pVB);
	SAFE_RELEASE(m_pIB);
	SAFE_RELEASE(m_pDecl);
	SAFE_RELEASE(m_pEffect);
}

HRESULT CGuiBorder::OnCreateDevice( IDirect3DDevice9* pd3dDevice )
{
    HRESULT hr = S_OK;
    // ------------------------ 以新的方式创建顶点流 -------------------------------
    LPD3DXMESH pMeshSysMemClone = NULL;
    D3DVERTEXELEMENT9 decl[] =
    {
		{ 0, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
		D3DDECL_END()
    };
    V_RETURN( pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl ));
    // ---------------------------------------------------------------------------
	std::wstring szRcPathOut;
	CommonFunc::RelativePath2FullPath( L"\\ResFile\\Support\\GuiEditor\\GuiBorder.fx", szRcPathOut );
    LPD3DXBUFFER pCode = NULL;
    if( FAILED( hr = D3DXCreateEffectFromFile( pd3dDevice, szRcPathOut.c_str(), NULL, NULL, 
		0, NULL, &m_pEffect, &pCode )))    
    {
        LPVOID pBufErr = pCode->GetBufferPointer();
        char* ErrInfo = ( char* ) pBufErr;
        pCode->Release();
        return hr;
    }
	CommonFunc::CheckFxWarning(pCode);

    return hr;
}

HRESULT CGuiBorder::OnResetDevice( IDirect3DDevice9* pd3dDevice )
{
    HRESULT hr = S_OK;
    V_RETURN(CreateSquare( pd3dDevice ));
	V_RETURN( m_pEffect->SetTechnique( "DefaultTech" ));
    return hr;
}

void CGuiBorder::OnFrameMove()
{
	HRESULT hr = S_OK;
	V( m_pEffect->SetInt( "g_OffsetX", m_nOffsetX ));
	V( m_pEffect->SetInt( "g_OffsetY", m_nOffsetY ));
	V( m_pEffect->SetInt( "g_Width", m_nWidth ));
	V( m_pEffect->SetInt( "g_Height", m_nHeight ));
	int nScreenWidth = 0, nScreenHeight = 0;
	CommonFunc::GetScreenWidthnHeight( &nScreenWidth, &nScreenHeight );
	V( m_pEffect->SetInt( "g_ScreenWidth", nScreenWidth ));
	V( m_pEffect->SetInt( "g_ScreenHeight", nScreenHeight ));
}

void CGuiBorder::OnFrameRender( IDirect3DDevice9* pd3dDevice )
{
    HRESULT hr = S_OK;
    V(pd3dDevice->SetVertexDeclaration( m_pDecl ));
    V(pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof( GUIBORDER_D3DVERTEX ))); 
    V(pd3dDevice->SetIndices( m_pIB )); 
    UINT iPass, cPasses;
    // ------------------------- ScreenShader ---------------------------
    V( m_pEffect->Begin( &cPasses, 0 ));
    for( iPass = 0; iPass < cPasses; iPass++ )
    {
        V( m_pEffect->BeginPass( iPass ));
		V( pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP , 0, 0, m_dwNumVertices, 0, 2 ));
        V( m_pEffect->EndPass() );
    }
    V( m_pEffect->End() );
}

void CGuiBorder::OnLostDevice()
{
	if (m_pEffect)
	{
		m_pEffect->OnLostDevice();
	}
	SAFE_RELEASE(m_pIB);
	SAFE_RELEASE(m_pVB);
}

void CGuiBorder::OnDestroyDevice()
{
	SAFE_RELEASE(m_pEffect);
	SAFE_RELEASE(m_pDecl);
	SAFE_RELEASE(m_pVB);
	SAFE_RELEASE(m_pIB);
}

HRESULT CGuiBorder::CreateSquare(LPDIRECT3DDEVICE9 pd3dDevice)
{
	HRESULT hr = S_OK;
	DWORD dwNumIndices = 4;        // 两个三角形共4个点
	m_dwNumVertices = 4;
	// ---------------------------- 创建索引缓冲区 ---------------------------
	{
		WORD* pIndices;
		V_RETURN(pd3dDevice->CreateIndexBuffer(dwNumIndices * sizeof(WORD),
			0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pIB, NULL));
		V_RETURN(m_pIB->Lock(0, 0, (void**)&pIndices, 0));
		// 
		pIndices[0] = 0;
		pIndices[1] = 1;
		pIndices[2] = 2;
		pIndices[3] = 3;
		V_RETURN(hr = m_pIB->Unlock());  // 写完肯定要解锁
	}
	// ---------------------------- 创建顶点缓冲区 ---------------------------
	{
		GUIBORDER_D3DVERTEX *pVertices;
		V_RETURN(pd3dDevice->CreateVertexBuffer(m_dwNumVertices * sizeof(GUIBORDER_D3DVERTEX),
			0, 0, D3DPOOL_DEFAULT, &m_pVB, NULL));

		V_RETURN(m_pVB->Lock(0, 0, (void**)&pVertices, 0));

		for (int i = 0; i < (int)m_dwNumVertices; ++i)
		{
			pVertices[i].VertexID = i;
		}

		V_RETURN(m_pVB->Unlock());
	}
	return hr;
}

void CGuiBorder::SetBorder(int nOffsetX, int nOffsetY, int nWidth, int nHeight)
{
	m_nOffsetX = nOffsetX;
	m_nOffsetY = nOffsetY;
	m_nWidth = nWidth;
	m_nHeight = nHeight;
}

bool CGuiBorder::IsRender()
{
	return m_nOffsetX != 0 || m_nOffsetY != 0 || m_nWidth != 0 || m_nHeight != 0;
}